home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / util / arc / LZHUtils_src.lha / Span.c < prev    next >
C/C++ Source or Header  |  1997-11-10  |  5KB  |  234 lines

  1. #define VERSION "2.0"
  2.  
  3. #define BUFFSIZE 512 /* Fragment size unit */
  4.  
  5. /* #define PC */
  6.  
  7. #include <fcntl.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <sys/stat.h>
  11. #include <unistd.h>
  12.  
  13. #ifdef PC
  14. #include <conio.h>
  15. #endif
  16.  
  17. enum EXIT_VALUE { SUCCESS, ERROR, ABORT };
  18. enum CONDITION { MUST, NEEDNT };
  19.  
  20. void usage(void);
  21. void span(char *infname, char *outfname, char *lastoutfname, char *outfext);
  22. void bind(char *infname, char *outfname, char *lastinfname, char *infext);
  23. void askdisk(char *type);
  24. void incrdisk(char *ext);
  25. char opensource(char *name, char condition);
  26. char opentarget(char *name);
  27. void readsource(unsigned bytes);
  28. char writetarget(unsigned bytes, char condition);
  29.  
  30. #define minimum(a, b) (a < b ? a : b)
  31.  
  32. unsigned char buff[BUFFSIZE];
  33. int infh, outfh;
  34. long infbytesleft;
  35. short disk = 0;
  36.  
  37. void usage(void)
  38. {
  39.     printf("Usage:\n"
  40.            "      span -s [source file] [target path]\n"
  41.            "      span -b [target file] [source path]\n\n"
  42.            "Examples:\n"
  43.            "      span -s c:/temp/dummy.zip a:/\n"
  44.            "      span -b c:/temp/dummy.zip a:/\n");
  45.     exit(ERROR);
  46. }
  47.  
  48. int main(int argc, char **argv)
  49. {
  50.     char name[FILENAME_MAX], lastname[FILENAME_MAX], *basename, spanit = 0;
  51.     int extpos;
  52. #ifdef PC
  53.     char *tmp;
  54. #endif
  55.  
  56.     printf("Span v%s. Copyright (c) 1996-1997 Konstantinos Tampouris, "
  57.            "Infinity Labs.\n\n", VERSION);
  58. #ifdef PC
  59.     if (!_USE_LFN)
  60.     {
  61.         printf("No long filename support found\n");
  62.         return(ERROR);
  63.     }
  64. #endif
  65.     if (argc != 4) usage();
  66.     if (!stricmp(argv[1], "-s"))
  67.         spanit = 1;
  68.     else if (stricmp(argv[1], "-b"))
  69.         usage();
  70. #ifdef PC
  71.     if ((basename = strrchr(argv[2], '/')) < (tmp = strrchr(argv[2], '\\')))
  72.         basename = tmp;
  73.     if (basename)
  74. #else
  75.     if (basename = strrchr(argv[2], '/'))
  76. #endif
  77.         basename++;
  78.     else
  79.         basename = argv[2];
  80.     extpos = strlen(basename) + strlen(argv[3]) + 1;
  81.     if (extpos + 4 > FILENAME_MAX)
  82.     {
  83.         printf("%s file name too big\n", (spanit ? "Targer" : "Source"));
  84.         return(ERROR);
  85.     }
  86.     sprintf(name, "%s%s.000", argv[3], basename);
  87.     sprintf(lastname, "%s%s.end", argv[3], basename);
  88.     if (spanit)
  89.         span(argv[2], name, lastname, &name[extpos]);
  90.     else
  91.         bind(name, argv[2], lastname, &name[extpos]);
  92.     return SUCCESS;
  93. }
  94.  
  95. void span(char *infname, char *outfname, char *lastoutfname, char *outfext)
  96. {
  97.     unsigned bytes = 0;
  98.     long outfsize;
  99.  
  100.     if (!opensource(infname, MUST)) exit(ERROR);
  101.     while (1)
  102.     {
  103.         askdisk("target");
  104.         remove(lastoutfname);
  105.         if (!opentarget(outfname)) continue;
  106.         while (infbytesleft)
  107.         {
  108.             if (!bytes) readsource(bytes = minimum(BUFFSIZE, infbytesleft));
  109.             if (!writetarget(bytes, NEEDNT)) break;
  110.             infbytesleft -= bytes;
  111.             bytes = 0;
  112.         }
  113.         outfsize = tell(outfh);
  114.         close(outfh);
  115.         if (!outfsize)
  116.         {
  117.             remove(outfname);
  118.             continue;
  119.         }
  120.         if (!infbytesleft) break;
  121.         incrdisk(outfext);
  122.     }
  123.     close(infh);
  124.     if (!disk) *(lastoutfname - outfname + outfext - 1) = 0;
  125.     rename(outfname, lastoutfname);
  126. }
  127.  
  128. void bind(char *infname, char *outfname, char *lastinfname, char *infext)
  129. {
  130.     char lastdisk = 0;
  131.     unsigned bytes;
  132.  
  133.     if (!opentarget(outfname)) exit(ERROR);
  134.     while (1)
  135.     {
  136.         askdisk("source");
  137.         if (!opensource(infname, NEEDNT))
  138.             if (opensource(lastinfname, NEEDNT))
  139.                 lastdisk = 1;
  140.             else
  141.                 continue;
  142.         while (infbytesleft)
  143.         {
  144.             readsource(bytes = minimum(BUFFSIZE, infbytesleft));
  145.             writetarget(bytes, MUST);
  146.             infbytesleft -= bytes;
  147.         }
  148.         close(infh);
  149.         if (lastdisk) break;
  150.         incrdisk(infext);
  151.     }
  152.     close(outfh);
  153. }
  154.  
  155. void askdisk(char *type)
  156. {
  157.     char c;
  158.  
  159.     printf("Insert disk #%hd in the %s drive and press [ENTER] - "
  160.            "Press [ESC] to quit", disk + 1, type);
  161.     fflush(stdout);
  162.     while ((c = getch()) != '\r')
  163.         if (c == '\e') /* ESC */
  164.         {
  165.             printf("\n");
  166.             exit(ABORT);
  167.         }
  168.     printf("\n");
  169. }
  170.  
  171. void incrdisk(char *ext)
  172. {
  173.     if (disk == 999)
  174.     {
  175.         printf("More than 1000 diskettes needed - Abort\n");
  176.         exit(ERROR);
  177.     }
  178.     sprintf(ext, "%03hd", ++disk);
  179. }
  180.  
  181. char opensource(char *name, char condition)
  182. {
  183.     if ((infh = open(name, O_RDONLY | O_BINARY)) < 0)
  184.     {
  185.         if (condition == MUST) printf("Error opening source file\n");
  186.         return 0;
  187.     }
  188.     lseek(infh, 0, SEEK_END);
  189.     if ((infbytesleft = tell(infh)) < 0)
  190.     {
  191.         close(infh);
  192.         printf("Error obtaining source file's size\n");
  193.         return 0;
  194.     }
  195.     lseek(infh, 0, SEEK_SET);
  196.     return 1;
  197. }
  198.  
  199. char opentarget(char *name)
  200. {
  201.     outfh = open(name, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT
  202. #ifdef PC
  203.     , S_IWUSR);
  204. #else
  205.     );
  206. #endif
  207.     if (outfh < 0)
  208.     {
  209.         printf("Error opening target file\n");
  210.         return 0;
  211.     }
  212.     return 1;
  213. }
  214.  
  215. void readsource(unsigned bytes)
  216. {
  217.     if (read(infh, buff, bytes) != bytes)
  218.     {
  219.         printf("Error reading source file\n");
  220.         exit(ERROR);
  221.     }
  222. }
  223.  
  224. char writetarget(unsigned bytes, char condition)
  225. {
  226.     if (write(outfh, buff, bytes) != bytes)
  227.     {
  228.         if (condition == NEEDNT) return 0;
  229.         printf("Error writing target file\n");
  230.         exit(ERROR);
  231.     }
  232.     return 1;
  233. }
  234.